/******************** (C) COPYRIGHT 2011 野火嵌入式开发工作室 ********************
 * 文件名  ：main.c
 * 描述    ：板载的LED1、LED2、LED3、以固定的频率轮流闪烁（频率可调）。         
 * 实验平台：野火STM32开发板
 * 库版本  ：ST3.0.0
 *
 * 作者    ：fire  QQ: 313303034 
 * 博客    ：firestm32.blog.chinaunix.net
**********************************************************************************/	

#include "stm32f10x.h"
#include "led.h"


#define APPLICATION_ADDRESS 0x08020000
typedef  void (*pFunction)(void);
void Delay(__IO u32 nCount);

void BootLoad_Jump(void);
#define WriteFlashAddress    ((u32)0x08020000)//读写起始地址（内部flash的主存储块地址从0x08000000开始）

/*******************************************************************************
* 函数名：Write_Flash
* 描述    ：写STM32指定地址的Flash
* 输入    ：buff:写入数据缓冲区，len:写入数据长度
* 输出    ：无
* 返回值    ：u8：写成功返回1，失败返回0
* 说明    ：无
*******************************************************************************/
u8 Write_Flash(u32 *buff, u8 len)
{    
    volatile FLASH_Status FLASHStatus;
    u8 k=0;
    u32 Address;

    Address = WriteFlashAddress;
    FLASHStatus = FLASH_COMPLETE;
    FLASH_Unlock();//解锁
//    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);//清除所有标志
    FLASHStatus = FLASH_ErasePage(WriteFlashAddress);//扇区擦除
    if(FLASHStatus == FLASH_COMPLETE)
    {
        for(k=0;(k<len) && (FLASHStatus == FLASH_COMPLETE);k++)
        {
            FLASHStatus = FLASH_ProgramWord(Address, buff[k]);//写入一个字（32位）的数据入指定地址
            Address = Address + 4;//地址偏移4个字节
        }        
        FLASH_Lock();//重新上锁，防止误写入
    }
    else
    {
        return 0;
    }
    if(FLASHStatus == FLASH_COMPLETE)
    {
        return 1;
    }
    return 0;
}

/*******************************************************************************
* 函数名：Read_Flash
* 描述    ：读STM32指定地址的Flash
* 输入    ：buff:读出数据缓冲区，len:读出数据长度
* 输出    ：无
* 返回值    ：无
* 说明    ：无
*******************************************************************************/
void Read_Flash(u16 *buff, u8 len, u32 Address)
{
    u8 k;
    for(k=0;k<len;k++)
    {
        buff[k] =  (*(vu16*) Address);//读指定地址的一个字的数据
        Address += 2;//地址偏移4个字节        
    }
}

/*
 * 函数名：main
 * 描述  ：主函数
 * 输入  ：无
 * 输出  ：无
 */
unsigned char flashinfo[100] = {1,1,1,1,1,1};
int main(void)
{
	//NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);
	/* 配置系统时钟为72M */      
	SystemInit();	
	
	/* LED 端口初始化 */
	LED_GPIO_Config();
	Read_Flash((u16*)flashinfo,100,0x8000000);
	BootLoad_Jump();
	while (1)
	{
//		Delay(0x6FFFEF);
//		LED3( ON );
//		Delay(0x6FFFEF);
//		LED3( OFF );      
	}

}

void Delay(__IO u32 nCount)
{
  for(; nCount != 0; nCount--);
} 

__asm void MSR_MSP(u32 addr) //设置堆栈指针
{
	MSR MSP, r0
	BX r14
}

void BootLoad_Jump(void)
{
	u32 JumpAddress;
	pFunction  Jump_To_Application;
    /* Check Vector Table: Test if user code is programmed starting from address 
    "APPLICATION_ADDRESS" */
    //d_printfhex32((*(__IO uint32_t*)APPLICATION_ADDRESS));d_printf("\n");
    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
    {
	__disable_irq();
    JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS +4);
    //d_printfhex32(JumpAddress);d_printf("\n");
    Delay(100);
    Jump_To_Application = (pFunction) JumpAddress;
    /* Initialize user application's Stack Pointer */
    MSR_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
    Jump_To_Application();
    }
}

/******************* (C) COPYRIGHT 2011 野火嵌入式开发工作室 *****END OF FILE****/
